#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/epoll.h>
#include "link.h"

/**--------------------------------------------------------------------------------
* 函数名称 :	CreateLinkHead
* 功能描述 :	创建链表头
* 入口参数 :	无
* 编辑作者 :	
* 返回值   ：   成功返回链表头的首地址， 失败返回NULL
* 备  注   ：   
---------------------------------------------------------------------------------*/
Link *CreateLinkHead()
{
	Link *head;
	head = malloc(sizeof(Link));
	
	if(head == NULL){
		perror("CreatLinkHead->malloc");
		return NULL;
	}

	memset(head,0,sizeof(Link));
	head->next = NULL;

	return head;
}

/**--------------------------------------------------------------------------------
* 函数名称 :	InsertLinkNode
* 功能描述 :	向链表中插入一个节点  头插
* 入口参数 :	Link *list    链表头
				LinkData  data  要插入的数据
* 编辑作者 :	
* 返回值   ：   成功返回0， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
int InsertLinkNode(Link *list, LinkData  data)
{
	Link  *node;
	
	if(!list)
		return -1;
	
	node = malloc(sizeof(Link));
	if(!node){
		perror("insert node");
		return -1;
	}
	bzero(node, sizeof(node));
	node->data = data;
	node->next = list->next;
	list->next = node;
	
	return 0;
}

/**--------------------------------------------------------------------------------
* 函数名称 :	DeleteLinkNode
* 功能描述 :	删除节点文件描述符为value处的值
* 入口参数 :	Link *list    链表头
				int value   要删除的文件描述符
* 编辑作者 :	
* 返回值   ：   成功返回0， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
int DeleteLinkNode(Link *list,int value)
{
	Link *p, *q;
	
	if(!list || value<0){
		printf("list is NULL or value error \n");
		return -1;
	}
	
	q = list;
	p = q->next;
	while(1){
		if(NULL==p)
			break;
		if(p->data.fd == value){
			q->next = p->next;
			p->next = NULL;
			free(p);
			return 0;
		}
		q = p;
		p = q->next;
	}
	return -1;
}

/**--------------------------------------------------------------------------------
* 函数名称 :	ChangeNodeData
* 功能描述 :	改变节点处的值
* 入口参数 :	Link *list    链表头
				LinkData data  要改变的值
* 编辑作者 :	
* 返回值   ：   成功返回0， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
int ChangeNodeData(Link *list, LinkData  data)
{
	Link *p;
	int fd = data.fd;
	
	if(!list){
		printf("list is NULL \n");
		return -1;
	}
	
	p = list->next;
	while(1){
		if(!p)
			break;
		if(p->data.fd == fd){
			p->data = data;
			return 0;
		}
		p = p->next;
	}
	return -1;
	
}

/**--------------------------------------------------------------------------------
* 函数名称 :	SearchLinkNode
* 功能描述 :	查找链表节点文件描述符为value处的值
* 入口参数 :	Link *list    链表头
				int value		要查找的值
				LinkData *data  存放要查找值的地址
* 编辑作者 :	
* 返回值   ：   成功返回0， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
Link* SearchLinkNode(Link *list, int value)
{
	Link *p;
	
	if(!list){
		return NULL;
	}
	p = list->next;
	
	while(1){
		if(!p){
			return NULL;
		}
		if(p->data.fd == value){
			return p;
		}
		p = p->next;
	}
}

/**--------------------------------------------------------------------------------
* 函数名称 :	ChangeNodeFlag
* 功能描述 :	改变节点处的标志位flag
* 入口参数 :	Link *list    链表头
				int fd		文件描述符
				int flag    要改变的flag值
* 编辑作者 :	
* 返回值   ：   成功返回0， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
int ChangeNodeFlag(Link *list, const int fd, int flag)
{
	Link *p;
	
	if(!list){
		printf("list is NULL \n");
		return -1;
	}
	
	p = list->next;
	while(1){
		if(!p)
			break;
		if(p->data.fd == fd){
			p->data.flag = flag;
			return 0;
		}
		p = p->next;
	}
	return -1;
	
}

/**--------------------------------------------------------------------------------
* 函数名称 :	GetNodeFlag
* 功能描述 :	获取节点处的标志位flag
* 入口参数 :	Link *list    链表头
				int fd		文件描述符
* 编辑作者 :	
* 返回值   ：   成功返回flag值， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
int GetNodeFlag(Link *list, const int fd)
{
	Link *p;
	
	if(!list){
		printf("list is NULL \n");
		return -1;
	}
	
	p = list->next;
	while(1){
		if(!p)
			break;
		if(p->data.fd == fd){
			return p->data.flag;
		}
		p = p->next;
	}
	return -1;
}

/**--------------------------------------------------------------------------------
* 函数名称 :	ClearLink
* 功能描述 :	清空链表，将套接字描述符从epoll列表中删除，并关闭文件描述符
* 入口参数 :	Link *list    链表头
				int epfd	  epoll文件描述符
* 编辑作者 :	
* 返回值   ：   成功返回0， 失败返回-1
* 备  注   ：   
---------------------------------------------------------------------------------*/
int ClearLink(Link *list, int epfd)
{
	Link *p;
	Link *q;
	int ret;
	int err_num = 0;
	
	if(!list){
		return -1;
	}
	p = list->next;
	list->next = NULL;
	
	while(1){
		if(NULL == p)
			break;
		q = p->next;
		p->next = NULL;
		ret = epoll_ctl(epfd, EPOLL_CTL_DEL, p->data.fd, NULL);
		if(ret < 0){
			err_num++;
			perror("ClearLink epoll_ctl");
			//return -1;
			continue;
		}
		close(p->data.fd);
		free(p);
		p = q;
	}
	if(err_num > 0){
		printf("ClearLink err_num = %d\n",err_num);
		return -1;
	}
	return 0;
	
}